/******************************************************************************* * Copyright (c) 2005, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.eclipse.dltk.internal.corext.refactoring.reorg; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.Assert; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.core.IMember; import org.eclipse.dltk.core.IMethod; import org.eclipse.dltk.core.IModelElement; import org.eclipse.dltk.core.IProjectFragment; import org.eclipse.dltk.core.IScriptFolder; import org.eclipse.dltk.core.IScriptProject; import org.eclipse.dltk.core.ISourceModule; import org.eclipse.dltk.core.ModelException; import org.eclipse.dltk.core.ScriptModelUtil; import org.eclipse.dltk.internal.core.ExternalSourceModule; import org.eclipse.dltk.internal.corext.refactoring.RefactoringCoreMessages; import org.eclipse.dltk.internal.corext.refactoring.util.ModelElementUtil; import org.eclipse.dltk.internal.corext.refactoring.util.ResourceUtil; import org.eclipse.dltk.internal.corext.util.Messages; import org.eclipse.ui.IWorkingSet; public class ReorgUtils { public static boolean containsOnlyProjects(List elements) { if (elements.isEmpty()) return false; for (Iterator iter = elements.iterator(); iter.hasNext();) { if (!isProject(iter.next())) return false; } return true; } public static boolean isProject(Object element) { return (element instanceof IScriptProject) || (element instanceof IProject); } public static boolean isInsideSourceModule(IModelElement element) { return !(element instanceof ISourceModule) && hasAncestorOfType(element, IModelElement.SOURCE_MODULE); } public static boolean hasAncestorOfType(IModelElement element, int type) { return element.getAncestor(type) != null; } public static ISourceModule getSourceModule(IModelElement modelElement) { if (modelElement instanceof ISourceModule) return (ISourceModule) modelElement; return (ISourceModule) modelElement .getAncestor(IModelElement.SOURCE_MODULE); } public static boolean isDeletedFromEditor(IModelElement elem) { if (!isInsideSourceModule(elem)) return false; if (elem instanceof IMember) {// && ((IMember)elem).isBinary()) return false; } ISourceModule cu = ReorgUtils.getSourceModule(elem); if (cu == null) return false; ISourceModule wc = cu; // TODO have to understand if this method is needed any longer. Since // with the new working copy support a element is never deleted from // the editor if we have a primary working copy. if (cu.equals(wc)) return false; IModelElement wcElement = ScriptModelUtil.findInSourceModule(wc, elem); return wcElement == null || !wcElement.exists(); } public static String getName(IModelElement element) throws ModelException { String pattern = createNamePattern(element); String[] args = createNameArguments(element); return Messages.format(pattern, args); } public static String getName(IResource resource) { String pattern = createNamePattern(resource); String[] args = createNameArguments(resource); return Messages.format(pattern, args); } private static String[] createNameArguments(IResource resource) { return new String[] { resource.getName() }; } private static String createNamePattern(IResource resource) { switch (resource.getType()) { case IResource.FILE: return RefactoringCoreMessages.ReorgUtils_0; case IResource.FOLDER: return RefactoringCoreMessages.ReorgUtils_1; case IResource.PROJECT: return RefactoringCoreMessages.ReorgUtils_2; default: Assert.isTrue(false); return null; } } private static String createNamePattern(IModelElement element) throws ModelException { switch (element.getElementType()) { case IModelElement.SOURCE_MODULE: if (element instanceof ExternalSourceModule) { return RefactoringCoreMessages.ReorgUtils_21; } else { return RefactoringCoreMessages.ReorgUtils_4; } case IModelElement.FIELD: return RefactoringCoreMessages.ReorgUtils_5; // case IModelElement.IMPORT_CONTAINER: // return RefactoringCoreMessages.ReorgUtils_6; // case IModelElement.IMPORT_DECLARATION: // return RefactoringCoreMessages.ReorgUtils_7; case IModelElement.SCRIPT_PROJECT: return RefactoringCoreMessages.ReorgUtils_9; case IModelElement.METHOD: if (((IMethod) element).isConstructor()) return RefactoringCoreMessages.ReorgUtils_10; else return RefactoringCoreMessages.ReorgUtils_11; // case IModelElement.PACKAGE_DECLARATION: // return RefactoringCoreMessages.ReorgUtils_12; case IModelElement.SCRIPT_FOLDER: if (ModelElementUtil.isDefaultPackage(element)) return RefactoringCoreMessages.ReorgUtils_13; else return RefactoringCoreMessages.ReorgUtils_14; case IModelElement.PROJECT_FRAGMENT: if (isSourceFolder(element)) return RefactoringCoreMessages.ReorgUtils_15; // if (isClassFolder(element)) // return RefactoringCoreMessages.ReorgUtils_16; return RefactoringCoreMessages.ReorgUtils_17; case IModelElement.TYPE: // IType type= (IType)element; return RefactoringCoreMessages.ReorgUtils_18; default: Assert.isTrue(false); return null; } } private static String[] createNameArguments(IModelElement element) throws ModelException { switch (element.getElementType()) { case IModelElement.SOURCE_MODULE: if (element instanceof ExternalSourceModule) { return new String[] { ((ExternalSourceModule) element) .getFullPath().toString() }; } else { return new String[] { element.getElementName() }; } case IModelElement.FIELD: return new String[] { element.getElementName() }; // case IModelElement.IMPORT_CONTAINER: // return new String[0]; // case IModelElement.IMPORT_DECLARATION: // return new String[]{element.getElementName()}; case IModelElement.SCRIPT_PROJECT: return new String[] { element.getElementName() }; case IModelElement.METHOD: return new String[] { element.getElementName() }; // case IModelElement.PACKAGE_DECLARATION: // if (ScriptElementUtil.isDefaultPackage(element)) // return new String[0]; // else // return new String[]{element.getElementName()}; case IModelElement.SCRIPT_FOLDER: return new String[] { element.getElementName() }; case IModelElement.PROJECT_FRAGMENT: return new String[] { element.getElementName() }; case IModelElement.TYPE: // IType type= (IType)element; // String name= type.getElementName(); return new String[] { element.getElementName() }; default: Assert.isTrue(false); return null; } } public static boolean isSourceFolder(IModelElement modelElement) throws ModelException { return (modelElement instanceof IProjectFragment) && ((IProjectFragment) modelElement) .getKind() == IProjectFragment.K_SOURCE; } public static IResource[] getResources(List elements) { List<IResource> resources = new ArrayList<>(elements.size()); for (Iterator iter = elements.iterator(); iter.hasNext();) { Object element = iter.next(); if (element instanceof IResource) resources.add((IResource) element); } return resources.toArray(new IResource[resources.size()]); } public static IResource getResource(IModelElement element) { if (element instanceof ISourceModule) return ((ISourceModule) element).getPrimary().getResource(); else return element.getResource(); } public static IResource[] getResources(IModelElement[] elements) { List<IResource> resultArray = new ArrayList<>(); for (int i = 0; i < elements.length; i++) { IResource res = ReorgUtils.getResource(elements[i]); if (res != null) { resultArray.add(res); } } return resultArray.toArray(new IResource[resultArray.size()]); } public static IResource[] getNotLinked(IResource[] resources) { Collection<IResource> result = new ArrayList<>(resources.length); for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; if (resource != null && !result.contains(resource) && !resource.isLinked()) result.add(resource); } return result.toArray(new IResource[result.size()]); } public static IResource[] getNotNulls(IResource[] resources) { Collection<IResource> result = new ArrayList<>(resources.length); for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; if (resource != null && !result.contains(resource)) result.add(resource); } return result.toArray(new IResource[result.size()]); } public static Map groupBySourceModule(List modelElements) { Map result = new HashMap(); for (Iterator iter = modelElements.iterator(); iter.hasNext();) { IModelElement element = (IModelElement) iter.next(); ISourceModule cu = ReorgUtils.getSourceModule(element); if (cu != null) { if (!result.containsKey(cu)) result.put(cu, new ArrayList(1)); ((List) result.get(cu)).add(element); } } return result; } public static List getElementsOfType(IModelElement[] modelElements, int type) { List result = new ArrayList(modelElements.length); for (int i = 0; i < modelElements.length; i++) { if (isOfType(modelElements[i], type)) result.add(modelElements[i]); } return result; } private static boolean isOfType(IModelElement element, int type) { return element.getElementType() == type;// this is _not_ a mask } private static boolean isOfType(IResource resource, int type) { return resource != null && isFlagSet(resource.getType(), type); } private static boolean isFlagSet(int flags, int flag) { return (flags & flag) != 0; } public static IModelElement[] setMinus(IModelElement[] setToRemoveFrom, IModelElement[] elementsToRemove) { Set<IModelElement> setMinus = new HashSet<>( setToRemoveFrom.length - setToRemoveFrom.length); setMinus.addAll(Arrays.asList(setToRemoveFrom)); setMinus.removeAll(Arrays.asList(elementsToRemove)); return setMinus.toArray(new IModelElement[setMinus.size()]); } public static IModelElement[] union(IModelElement[] set1, IModelElement[] set2) { List<IModelElement> union = new ArrayList<>(set1.length + set2.length);// use // lists // to // avoid // sequence // problems addAll(set1, union); addAll(set2, union); return union.toArray(new IModelElement[union.size()]); } public static IResource[] union(IResource[] set1, IResource[] set2) { List<IResource> union = new ArrayList<>(set1.length + set2.length);// use // lists // to // avoid // sequence // problems addAll(ReorgUtils.getNotNulls(set1), union); addAll(ReorgUtils.getNotNulls(set2), union); return union.toArray(new IResource[union.size()]); } private static void addAll(Object[] array, List list) { for (int i = 0; i < array.length; i++) { if (!list.contains(array[i])) list.add(array[i]); } } public static IResource[] setMinus(IResource[] setToRemoveFrom, IResource[] elementsToRemove) { Set<IResource> setMinus = new HashSet<>( setToRemoveFrom.length - setToRemoveFrom.length); setMinus.addAll(Arrays.asList(setToRemoveFrom)); setMinus.removeAll(Arrays.asList(elementsToRemove)); return setMinus.toArray(new IResource[setMinus.size()]); } public static IModelElement[] getModelElements(List elements) { List<IModelElement> resources = new ArrayList<>(elements.size()); for (Iterator iter = elements.iterator(); iter.hasNext();) { Object element = iter.next(); if (element instanceof IModelElement) resources.add((IModelElement) element); } return resources.toArray(new IModelElement[resources.size()]); } public static ISourceModule[] getSourceModules( IModelElement[] modelElements) { ISourceModule[] result = new ISourceModule[modelElements.length]; for (int i = 0; i < modelElements.length; i++) { result[i] = getSourceModule(modelElements[i]); } return result; } public static IWorkingSet[] getWorkingSets(List elements) { List<IWorkingSet> result = new ArrayList<>(1); for (Iterator iter = elements.iterator(); iter.hasNext();) { Object element = iter.next(); if (element instanceof IWorkingSet) { result.add((IWorkingSet) element); } } return result.toArray(new IWorkingSet[result.size()]); } public static void splitIntoModelElementsAndResources(Object[] elements, List modelElementResult, List resourceResult) { for (int i = 0; i < elements.length; i++) { Object element = elements[i]; if (element instanceof IModelElement) { modelElementResult.add(element); } else if (element instanceof IResource) { IResource resource = (IResource) element; IModelElement jElement = DLTKCore.create(resource); if (jElement != null && jElement.exists()) modelElementResult.add(jElement); else resourceResult.add(resource); } } } public static boolean containsElementOrParent(Set elements, IModelElement element) { if (elements.contains(element)) return true; IModelElement parent = element.getParent(); while (parent != null) { if (elements.contains(parent)) return true; parent = parent.getParent(); } return false; } public static boolean containsElementOrParent(Set elements, IResource element) { if (elements.contains(element)) return true; IResource parent = element.getParent(); while (parent != null) { if (elements.contains(parent)) return true; IModelElement parentAsScriptElement = DLTKCore.create(parent); if (parentAsScriptElement != null && parentAsScriptElement.exists() && elements.contains(parentAsScriptElement)) return true; parent = parent.getParent(); } return false; } public static boolean hasElementsNotOfType(IResource[] resources, int typeMask) { for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; if (resource != null && !isOfType(resource, typeMask)) return true; } return false; } public static boolean hasElementsNotOfType(IModelElement[] modelElements, int type) { for (int i = 0; i < modelElements.length; i++) { IModelElement element = modelElements[i]; if (element != null && !isOfType(element, type)) return true; } return false; } public static boolean canBeDestinationForLinkedResources( IResource resource) { return resource.isAccessible() && resource instanceof IProject; } public static boolean canBeDestinationForLinkedResources( IModelElement modelElement) { if (modelElement instanceof IProjectFragment) { return isProjectFragmentCorrespondingToProject( (IProjectFragment) modelElement); } else if (modelElement instanceof IScriptProject) { return true;// XXX ??? } else return false; } private static boolean isProjectFragmentCorrespondingToProject( IProjectFragment root) { return root.getResource() instanceof IProject; } public static boolean isArchiveOrExterrnalMember(IModelElement[] elements) { for (int i = 0; i < elements.length; i++) { IModelElement element = elements[i]; IProjectFragment root = (IProjectFragment) element .getAncestor(IModelElement.PROJECT_FRAGMENT); if (root != null && (root.isArchive() || root.isExternal())) return true; } return false; } public static boolean hasElementsOfType(IModelElement[] modelElements, int type) { for (int i = 0; i < modelElements.length; i++) { IModelElement element = modelElements[i]; if (element != null && isOfType(element, type)) return true; } return false; } public static boolean hasElementsOfType(IModelElement[] modelElements, int[] types) { for (int i = 0; i < types.length; i++) { if (hasElementsOfType(modelElements, types[i])) return true; } return false; } public static boolean hasElementsOfType(IResource[] resources, int typeMask) { for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; if (resource != null && isOfType(resource, typeMask)) return true; } return false; } public static IFile[] getFiles(IResource[] resources) { Set result = getResourcesOfType(resources, IResource.FILE); return (IFile[]) result.toArray(new IFile[result.size()]); } public static Set getResourcesOfType(IResource[] resources, int typeMask) { Set result = new HashSet(resources.length); for (int i = 0; i < resources.length; i++) { if (isOfType(resources[i], typeMask)) result.add(resources[i]); } return result; } public static IFolder[] getFolders(IResource[] resources) { Set result = getResourcesOfType(resources, IResource.FOLDER); return (IFolder[]) result.toArray(new IFolder[result.size()]); } public static IProjectFragment getCorrespondingProjectFragment( IScriptProject p) throws ModelException { IProjectFragment[] roots = p.getProjectFragments(); for (int i = 0; i < roots.length; i++) { if (isProjectFragmentCorrespondingToProject(roots[i])) return roots[i]; } return null; } public static boolean containsLinkedResources(IResource[] resources) { for (int i = 0; i < resources.length; i++) { if (resources[i] != null && resources[i].isLinked()) return true; } return false; } public static boolean containsLinkedResources( IModelElement[] modelElements) { for (int i = 0; i < modelElements.length; i++) { IResource res = getResource(modelElements[i]); if (res != null && res.isLinked()) return true; } return false; } public static boolean isProjectFragment(IScriptProject scriptProject) throws ModelException { return getCorrespondingProjectFragment(scriptProject) != null; } public static boolean areEqualInWorkspaceOrOnDisk(IResource r1, IResource r2) { if (r1 == null || r2 == null) return false; if (r1.equals(r2)) return true; URI r1Location = r1.getLocationURI(); URI r2Location = r2.getLocationURI(); if (r1Location == null || r2Location == null) return false; return r1Location.equals(r2Location); } public static boolean isParentInWorkspaceOrOnDisk(IScriptFolder pack, IProjectFragment root) { if (pack == null) return false; IModelElement packParent = pack.getParent(); if (packParent == null) return false; if (packParent.equals(root)) return true; IResource packageResource = ResourceUtil.getResource(pack); IResource packageRootResource = ResourceUtil.getResource(root); return isParentInWorkspaceOrOnDisk(packageResource, packageRootResource); } public static boolean isParentInWorkspaceOrOnDisk(IProjectFragment root, IScriptProject scriptProject) { if (root == null) return false; IModelElement rootParent = root.getParent(); if (rootParent == null) return false; if (rootParent.equals(root)) return true; IResource packageResource = ResourceUtil.getResource(root); IResource packageRootResource = ResourceUtil.getResource(scriptProject); return isParentInWorkspaceOrOnDisk(packageResource, packageRootResource); } public static boolean isParentInWorkspaceOrOnDisk(ISourceModule cu, IScriptFolder dest) { if (cu == null) return false; IModelElement cuParent = cu.getParent(); if (cuParent == null) return false; if (cuParent.equals(dest)) return true; IResource cuResource = ResourceUtil.getResource(cu); IResource packageResource = ResourceUtil.getResource(dest); return isParentInWorkspaceOrOnDisk(cuResource, packageResource); } public static boolean isParentInWorkspaceOrOnDisk(IResource res, IResource maybeParent) { if (res == null) return false; return areEqualInWorkspaceOrOnDisk(res.getParent(), maybeParent); } }